using System;
using System.Collections.Generic;
using System.Linq.Expressions;

using Preactor.Interop.PreactorObject;
using Preactor.ObjectModel.Entities;
using Preactor.ObjectModel.Interfaces;

namespace Preactor.ObjectModel
{
    public interface IPreactorObjectModel
    {
    // Add some documentation
        IPreactor Preactor { get; }

        Dictionary<Type, List<string>> TypePreactorFields { get; }

        void ClearCacheForType(Type implementedType);

        void DeleteRecord<T>(T preactorRecord) where T : IPreactorRecord;

        IEnumerable<TInterface> GetAllRecords<TInterface>() where TInterface : class, IPreactorRecord;

        FormatFieldPair GetFormatFieldPair<TInterface>(Expression<Func<TInterface, object>> keySelector);

        FormatFieldPair GetFormatFieldPair(string propertyName, Type implementedType);

        string GetFormatName<TInterface>();

        string GetFormatNameByType(Type implemetedType);

        int GetFormatNumber<TInterface>();

        int GetFormatNumberByType(Type implementedType);

        TInterface GetRecord<TInterface>(int recordNumber) where TInterface : class, IPreactorRecord;

        TInterface CreateRecord<TInterface>() where TInterface : class, IPreactorRecord;

        TInterface GetRecord<TInterface>(PrimaryKey pk) where TInterface : class, IPreactorRecord;

        TInterface GetRecordByName<TInterface>(string name) where TInterface : class, IPreactorRecord;

        void LoadPreactorObject(PreactorObj preactorObject);

        /// <summary>
        /// static PreactorObjectModel
        /// The last type to be registered against an interface will win
        /// </summary>
        /// <typeparam name="TInterface"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <param name="formatName"></param>
        void Register<TInterface, TType>(string formatName = null) where TType : PreactorRecord, TInterface;

        Type ResolveType<TInterface>();
    }
}
